package com.yanqu.road.server.gameplayer.module.activity.langyamemorial;

import com.yanqu.road.dao.impl.activity.langyamemorial.LangYaMemorialUserDataDaoImpl;
import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.args.ValueFourParamArgs;
import com.yanqu.road.entity.activity.args.ValueParamArgs;
import com.yanqu.road.entity.activity.langyamemorial.LangYaMemorialLight;
import com.yanqu.road.entity.activity.langyamemorial.LangYaMemorialUserData;
import com.yanqu.road.entity.activity.langyamemorial.config.LangYaMemorialAtticInfo;
import com.yanqu.road.entity.activity.langyamemorial.config.LangYaMemorialConfig;
import com.yanqu.road.entity.config.goods.GoodsInfo;
import com.yanqu.road.entity.config.goods.OpenGoodsBagResult;
import com.yanqu.road.entity.enums.eGamePlayerEventType;
import com.yanqu.road.entity.enums.eLogMoneyType;
import com.yanqu.road.entity.enums.eSystemId;
import com.yanqu.road.entity.log.LogLangYaBuild;
import com.yanqu.road.entity.log.LogLangYaLightReward;
import com.yanqu.road.pb.activity.LangYaMemorialProto;
import com.yanqu.road.server.GameServer;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.activity.ActivityModule;
import com.yanqu.road.server.gameplayer.module.base.GeneralModule;
import com.yanqu.road.server.gameplayer.module.player.CurrencyModule;
import com.yanqu.road.server.gameplayer.module.player.PreReduceModule;
import com.yanqu.road.server.logic.activity.BaseActivityData;
import com.yanqu.road.server.logic.activity.condition.BaseActivityCondition;
import com.yanqu.road.server.manger.ServerLanguageMgr;
import com.yanqu.road.server.manger.activity.ActivityMgr;
import com.yanqu.road.server.manger.activity.langyamemorial.LangYaMemorialMgr;
import com.yanqu.road.server.manger.config.GoodsBagMgr;
import com.yanqu.road.server.manger.config.GoodsMgr;
import com.yanqu.road.server.manger.config.SystemOpenMgr;
import com.yanqu.road.server.manger.log.AutoLogMgr;
import com.yanqu.road.server.pb.PlayerPb;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.Protocol;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;
import com.yanqu.road.utils.string.StringUtils;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class LangYaMemorialModule extends GeneralModule {

    private LangYaMemorialUserData userData;

    private Random random = new Random();
    
    public LangYaMemorialModule(GamePlayer player) {
        super(player);
    }

    @Override
    public boolean loadData() {
        ActivityInfo activityInfo = LangYaMemorialMgr.getActivityInfo();
        if(ActivityMgr.activityInShowTime(activityInfo)) {
            userData = new LangYaMemorialUserDataDaoImpl().getLangYaMemorialUserData(activityInfo.getActivityId(), player.getUserId());
        }
        return true;
    }

    @Override
    public boolean afterLoadData() {
        return true;
    }

    @Override
    public boolean saveData() {
        if(userData != null){
            if(userData.isInsertOption()){
                new LangYaMemorialUserDataDaoImpl().add(userData);
            } else if (userData.isUpdateOption()) {
                new LangYaMemorialUserDataDaoImpl().update(userData);
            }
        }
        return true;
    }

    @Override
    public void afterLogin() {

        if (!SystemOpenMgr.systemOpen(player, eSystemId.LangYaMemorial.getValue())) {
            return;
        }

        syncConfig();

        syncUserData();

        int activityId = LangYaMemorialMgr.getActivityId();
        Long buildValue = LangYaMemorialMgr.getCacheAllBuildValueMap().get(activityId);
        if(buildValue != null){
            updateAllBuildValue(activityId, buildValue);
        }
    }

    public void syncConfig() {
        LangYaMemorialConfig config = LangYaMemorialMgr.getConfig();
        if (config == null || !ActivityMgr.activityInShowTime(config.getActivityInfo())) {
            return;
        }

        LangYaMemorialProto.LangYaMemorialConfigDataSyncMsg.Builder configSync = LangYaMemorialProto.LangYaMemorialConfigDataSyncMsg.newBuilder();
        for (LangYaMemorialAtticInfo atticInfo : config.getAtticInfoList()) {
            LangYaMemorialProto.LangYaMemorialAtticConfig.Builder builder = LangYaMemorialProto.LangYaMemorialAtticConfig.newBuilder();
            builder.setRewardId(atticInfo.getRewardId());
            builder.setType(atticInfo.getId());
            builder.setWeight(atticInfo.getFalseWeight());
            builder.setIsNotice(atticInfo.getIsNotice());
            builder.setSort(atticInfo.getSort());
            builder.setReward(atticInfo.getReward());
            configSync.addAttic(builder);
        }
        configSync.setATTICNPCNAME(ServerLanguageMgr.getContent(config.getATTIC_NPC_NAME(), player.getLanguage()));
        player.sendPacket(Protocol.U_LANGYA_MEMORIAL_SYNC_CONFIG, configSync);
    }

    public synchronized void initUserData() {
        // 系统未解锁
        if (!SystemOpenMgr.systemOpen(player, eSystemId.LangYaMemorial.getValue())) {
            return;
        }

        // 没有活动
        if (!ActivityMgr.activityInShowTime(LangYaMemorialMgr.getActivityInfo()) || LangYaMemorialMgr.getConfig() == null) {
            return;
        }

        ActivityInfo activityInfo = LangYaMemorialMgr.getActivityInfo();

        // 已经有数据了
        if (userData != null && userData.getActivityId() == activityInfo.getActivityId()) {
            return;
        }

        LangYaMemorialConfig config = LangYaMemorialMgr.getConfig();

        LangYaMemorialUserData tmpUserData = new LangYaMemorialUserData();

        tmpUserData.setActivityId(activityInfo.getActivityId());
        tmpUserData.setUserId(getUserId());
        tmpUserData.setLightList(new ArrayList<>());
        tmpUserData.setInsertOption();
        userData = tmpUserData;
    }

    public void syncUserData() {
        LangYaMemorialConfig config = LangYaMemorialMgr.getConfig();
        if (config == null || !ActivityMgr.activityInShowTime(config.getActivityInfo())) {
            return;
        }

        if(SystemOpenMgr.systemOpen(player, eSystemId.LangYaMemorial.getValue())){
            if(userData == null || userData.getActivityId() != LangYaMemorialMgr.getActivityId()){
                initUserData();
            }
        }

        if(userData == null){
            return;
        }

        LangYaMemorialProto.LangYaMemorialUserDataSyncMsg.Builder syncMsg = LangYaMemorialProto.LangYaMemorialUserDataSyncMsg.newBuilder();
        LangYaMemorialProto.LangYaMemorialUserData.Builder builder = LangYaMemorialActivityPb.buildUserData(userData);
        syncMsg.setUserData(builder);
        player.sendPacket(Protocol.U_LANGYA_MEMORIAL_SYNC_USER_DATA, syncMsg);
    }

    /**
     * 建阁
     */
    public int buildAttic(int type) {
        if(userData == null){
            return GameErrorCode.E_SYSTEM_NO_OPEN;
        }
        int times = 1;
        if(type == 1){
            times = 10;
        }

        LangYaMemorialConfig config = LangYaMemorialMgr.getConfig();
        if(config == null){
            return GameErrorCode.E_ACTIVITY_OVER_TIME;
        }

        if(type == 1){
            if(userData.getScore() < config.getAtticTenConsumeCond()){
                return GameErrorCode.E_LANG_YA_MEMORIAL_SCORE_NO_ENOUGH;
            }
        }

        //消耗
        Property consume = PropertyHelper.parseStringToProperty(config.getAtticConsume());
        if(times == 10){
            consume = PropertyHelper.parseStringToProperty(config.getAtticTenConsume());
        }
        if(!player.getModule(CurrencyModule.class).currencyIsEnough(consume)){
            return GameErrorCode.E_BAG_ITEM_NO_ENOUGH;
        }

        //预扣
        player.getModule(PreReduceModule.class).preReduce(consume);

        //格子类型， 1 黄金阁  2 普通阁
        List<Integer> cellTypeList = new ArrayList<>();
        int commonTimes = userData.getCommonTimes();
        for (int i = 0; i < times; i++) {
            commonTimes++;
            if(commonTimes % config.getGoldFloors() == 0){
                //保底触发
                cellTypeList.add(1);
                commonTimes = 0;
                continue;
            }
            if(random.nextInt(1000) < config.getGoldProbability()){
                //概率触发
                cellTypeList.add(1);
                commonTimes = 0;
            }else {
                cellTypeList.add(2);
            }
        }

        //进度值
        int buildValue = 0;
        for (int i = 0; i < cellTypeList.size(); i++) {
            int t = cellTypeList.get(i);
            buildValue += config.getBuildValue(t);
        }

        //上跨服
        LangYaMemorialProto.CrossLangYaMemorialBuildReqMsg.Builder crossReq = LangYaMemorialProto.CrossLangYaMemorialBuildReqMsg.newBuilder();
        crossReq.setActivityId(userData.getActivityId());
        crossReq.setConsume(PropertyHelper.parsePropertyToString(consume));
        crossReq.setBuildValue(userData.getBuildValue() + buildValue);
        crossReq.addAllType(cellTypeList);
        crossReq.setCommonTimes(commonTimes);
        crossReq.setBaseInfo(PlayerPb.parsePlayerBaseTempMsg(player.getUserInfo()));
        player.sendPacket(Protocol.C_LANGYA_MEMORIAL_BUILD, crossReq);
        return 0;
    }

    /**
     * 建阁  跨服返回
     */
    public int buildAtticFromCross(String consume, int commonTimes, List<Integer> typeList, List<LangYaMemorialProto.LangYaMemorialAtticData> list) {

        player.getModule(PreReduceModule.class).restorePreReduce(consume);

        if(!player.getModule(CurrencyModule.class).removeCurrency(PropertyHelper.parseStringToProperty(consume), eLogMoneyType.LangYaMemorial, eLogMoneyType.LangYaMemorialBuildAtticConsume)){
            LangYaMemorialMgr.getLogger().info("activity {} user {} consume {} no enough ", userData.getActivityId(), userData.getUserId(), consume);
            return GameErrorCode.E_BAG_ITEM_NO_ENOUGH;
        }

        LangYaMemorialProto.LangYaMemorialUploadNoticeMsg.Builder noticeUploadBuilder = LangYaMemorialProto.LangYaMemorialUploadNoticeMsg.newBuilder();

        LangYaMemorialConfig config = LangYaMemorialMgr.getConfig();
        int times = typeList.size();
        //积分奖励
        int integral = times * config.getAtticIntegral();
        String reward = PropertyHelper.parseGoodsToString(config.getEXCHANGE_SCORE_ITEM_ID(), BigInteger.valueOf(integral));

        Property goodsReward = new Property();

        //进度值
        int buildValue = 0;
        //合并公告
        Property noticeReward = new Property();
        int atticInfoId = 0;
        for (int i = 0; i < typeList.size(); i++) {
            int t = typeList.get(i);
            LangYaMemorialAtticInfo atticInfo =  config.random(t, random);
            goodsReward.addProperty(PropertyHelper.parseStringToProperty(atticInfo.getReward()));
            buildValue += config.getBuildValue(t);

            //是否公告
            if(atticInfo.getIsNotice() == 1){
                atticInfoId = atticInfo.getId();
                noticeReward.addProperty(PropertyHelper.parseStringToProperty(atticInfo.getReward()));
            }
        }

        if(!noticeReward.isNothing()){
            LangYaMemorialProto.LangYaMemorialNoticeMsg.Builder notice = LangYaMemorialProto.LangYaMemorialNoticeMsg.newBuilder();
            notice.setType(atticInfoId);
            notice.setNickName(player.getUserInfo().getNickName());
            notice.setReward(PropertyHelper.parsePropertyToString(noticeReward));
            notice.setServerId(GameServer.getInstance().getServerId());
            notice.setTime(System.currentTimeMillis());
            noticeUploadBuilder.addNotice(notice);
        }

        int goldTimes = 0;
        List<Integer> addLightList = new ArrayList<>();
        //长明灯
        int dengNum = userData.getLightList().size();
        for (int t : typeList) {
            if(t == 1){
                LangYaMemorialLight light = new LangYaMemorialLight();
                light.setId(++dengNum);
                userData.getLightList().add(light);
                userData.setBigRewardTimes(1 + userData.getBigRewardTimes());
                goldTimes++;
                addLightList.add(dengNum);
            }
        }

        goodsReward.addProperty(PropertyHelper.parseStringToProperty(reward));
        userData.setBuildValue(userData.getBuildValue() + buildValue);
        userData.setCommonTimes(commonTimes);
        userData.setBuildTimes(userData.getBuildTimes() + times);
        userData.setScore(userData.getScore() + integral);
        player.getModule(CurrencyModule.class).addCurrency(goodsReward, eLogMoneyType.LangYaMemorial, eLogMoneyType.LangYaMemorialBuildAtticReward);

        //日志
        AutoLogMgr.add(new LogLangYaBuild(userData.getActivityId(),
                userData.getUserId(),
                integral,
                buildValue,
                StringUtils.listToString(typeList, ","),
                PropertyHelper.parsePropertyToString(goodsReward),
                StringUtils.listToString(addLightList, ",")));

        //其他成就
        player.notifyListener(eGamePlayerEventType.LangYaMemorialBuildTimes.getValue(), userData.getBuildTimes());

        LangYaMemorialProto.LangYaMemorialBuildRespMsg.Builder clientMsg = LangYaMemorialProto.LangYaMemorialBuildRespMsg.newBuilder().setRet(0);
        clientMsg.setUserData(LangYaMemorialActivityPb.buildUserData(userData));
        clientMsg.setReward(PropertyHelper.parsePropertyToString(goodsReward));
        clientMsg.setBuildValue(buildValue);
        clientMsg.setLightSize(goldTimes);
        clientMsg.addAllList(list);
        player.sendPacket(Protocol.U_LANGYA_MEMORIAL_BUILD, clientMsg);

        player.notifyListener(eGamePlayerEventType.LangYaMemorialCrossRank.getValue(), new ValueParamArgs(userData.getScore(), ""));

        //公告
        if(noticeUploadBuilder.getNoticeCount() > 0){
            noticeUploadBuilder.setActivityId(config.getActivityInfo().getActivityId());
            player.sendPacket(Protocol.C_LANGYA_MEMORIAL_NOTICE_UPLOAD, noticeUploadBuilder);
        }
        return 0;
    }

    /**
     * 残卷修复
     * @param process
     */
    public int repair(int process) {
        if(userData == null){
            return GameErrorCode.E_SYSTEM_NO_OPEN;
        }

        LangYaMemorialConfig config = LangYaMemorialMgr.getConfig();
        if(config == null){
            return GameErrorCode.E_ACTIVITY_OVER_TIME;
        }

        BaseActivityCondition maxActivityCondition = null;
        //进度上限控制
        BaseActivityData baseActivityData = player.getModule(ActivityModule.class).getBaseActivityData(userData.getActivityId());
        if(baseActivityData != null) {
            int conditionId = 0;
            for (BaseActivityCondition baseActivityCondition : baseActivityData.getBaseActivityConditionList()) {
                if (baseActivityCondition.getConditionType() == eGamePlayerEventType.LangYaMemorialRepairProgress.getValue()) {
                    if (baseActivityCondition.getConditionId() > conditionId) {
                        maxActivityCondition = baseActivityCondition;
                        conditionId = baseActivityCondition.getConditionId();
                    }
                }
            }
        }

        if(maxActivityCondition == null){
            return GameErrorCode.E_ERROR_DATA;
        }

        if(userData.getProgress() + process > maxActivityCondition.getActivityConditionInfo().getParamList().get(3).intValue()){
            return GameErrorCode.E_REQUEST_ARGUMENT_ERROR;
        }

        if(maxActivityCondition.isCompleted(player)){
            return GameErrorCode.E_LANG_YA_MEMORIAL_REPAIR_PROCESS_END;
        }

        //消耗
        Property consume = PropertyHelper.parseStringToProperty(config.getRepairProp());
        consume.rideProperty(process);
        if(!player.getModule(CurrencyModule.class).removeCurrency(consume, eLogMoneyType.LangYaMemorial, eLogMoneyType.LangYaMemorialRepairConsume)){
            return GameErrorCode.E_BAG_ITEM_NO_ENOUGH;
        }

        userData.setProgress(process + userData.getProgress());
        player.notifyListener(eGamePlayerEventType.LangYaMemorialRepairProgress.getValue(), userData.getProgress());

        String reward = "";
        if(maxActivityCondition.isCompleted(player)){
            reward = maxActivityCondition.getReward();
        }

        LangYaMemorialProto.LangYaMemorialRepairRespMsg.Builder builder = LangYaMemorialProto.LangYaMemorialRepairRespMsg.newBuilder().setRet(0);
        builder.setProcess(process);
        builder.setUserData(LangYaMemorialActivityPb.buildUserData(userData));
        //大奖
        builder.setReward(reward);
        player.sendPacket(Protocol.U_LANGYA_MEMORIAL_REPAIR, builder);
        return 0;
    }

    public void updateAllBuildValue(int activityId, long buildValue) {
        if(userData == null){
            return;
        }
        if(userData.getActivityId() == activityId){
            player.notifyListener(eGamePlayerEventType.LangYaMemorialBuildAllValue.getValue(), buildValue);
            LangYaMemorialProto.LangYaMemorialProcessSync.Builder sync = LangYaMemorialProto.LangYaMemorialProcessSync.newBuilder();
            sync.setBuildValue(buildValue);
            player.sendPacket(Protocol.U_LANGYA_MEMORIAL_SYNC_BUILD_VALUE, sync);
        }
    }


    public LangYaMemorialUserData getUserData() {
        return userData;
    }

    /**
     * 长明灯领奖
     */
    public int getLightReward(int id) {
        if(userData == null){
            return GameErrorCode.E_SYSTEM_NO_OPEN;
        }

        LangYaMemorialConfig config = LangYaMemorialMgr.getConfig();
        if(config == null){
            return GameErrorCode.E_ACTIVITY_OVER_TIME;
        }

        List<Integer> configList = StringUtils.stringToIntegerList(config.getKongmingReward(), "\\|");
        int val = configList.get(0);
        int boxId = configList.get(1);
        GoodsInfo info = GoodsMgr.getGoodsById(boxId);
        if(info == null){
            return GameErrorCode.E_GOODS_NO_EXIST;
        }

        List<Integer> getIdList = new ArrayList<>();
        List<LangYaMemorialLight> list = new ArrayList<>();
        for (LangYaMemorialLight light : userData.getLightList()) {
            if(id > 0 && light.getId() == id){
                if(light.getGet() == 0){
                    light.setGet(1);
                    list.add(light);
                    getIdList.add(light.getId());
                }
                break;
            }
            if(id == 0){
                if(light.getGet() == 0){
                    light.setGet(1);
                    list.add(light);
                    getIdList.add(light.getId());
                }
            }
        }

        if(list.size() == 0){
            return GameErrorCode.E_ACTIVITY_REWARD_IS_GET;
        }

        int addVal = 0;
        Property reward = new Property();
        for (LangYaMemorialLight light : list) {
            light.setGet(1);
            addVal += val;
            OpenGoodsBagResult openGoodsBagResult = GoodsBagMgr.getRandomGoods(boxId);
            reward.addProperty(openGoodsBagResult.getReward());
        }

        //日志
        AutoLogMgr.add(new LogLangYaLightReward(userData.getActivityId(),
                userData.getUserId(),
                StringUtils.listToString(getIdList, ","),
                addVal,
                PropertyHelper.parsePropertyToString(reward)
                ));

        userData.setBuildValue(userData.getBuildValue() + addVal);
        player.getModule(CurrencyModule.class).addCurrency(reward, eLogMoneyType.LangYaMemorial, eLogMoneyType.LangYaMemorialBuildLightReward);

        //上传进度
        LangYaMemorialProto.CrossLangYaMemorialUploadUserValueMsg.Builder upload = LangYaMemorialProto.CrossLangYaMemorialUploadUserValueMsg.newBuilder();
        upload.setActivityId(userData.getActivityId());
        upload.setUserId(player.getUserId());
        upload.setBuildValue(userData.getBuildValue());
        upload.setNeedSync(true);
        player.sendPacket(Protocol.C_LANGYA_MEMORIAL_UPLOAD_USER_BUILD_VALUE, upload);

        LangYaMemorialProto.LangYaMemorialGetLightRewardRespMsg.Builder respMsg = LangYaMemorialProto.LangYaMemorialGetLightRewardRespMsg.newBuilder();
        respMsg.setRet(0);
        respMsg.setBuildValue(addVal);
        respMsg.setUserData(LangYaMemorialActivityPb.buildUserData(userData));
        respMsg.setReward(PropertyHelper.parsePropertyToString(reward));
        player.sendPacket(Protocol.U_LANGYA_MEMORIAL_LIGHT_GET_REWARD, respMsg);

        return 0;
    }
}
